package com.twu.biblioteca.items;

import com.twu.biblioteca.library.ILibraryItemCollector;

/**
 * @author Alvi Jonathan Sait
 */
public class Movie implements ILibraryItem, Comparable<Movie> {

    private final String movieId;
    private final String title;
    private final String director;
    private final int year;
    private final Rating rating;
    private boolean isAvailable;

    public Movie(String movieId, String title, String director, int year, Rating rating) {
        this.movieId = movieId;
        this.title = title;
        this.director = director;
        this.year = year;
        this.rating = rating;
        setAvailable(true);
    }

    public String getMovieId() {
        return movieId;
    }

    public String getTitle() {
        return title;
    }

    public String getDirector() {
        return director;
    }

    public int getYear() {
        return year;
    }

    public Rating getRating() {
        return rating;
    }

    @Override
    public void acceptCheckouter(ILibraryItemCollector collector) {
        collector.checkoutMovie(this);
    }

    @Override
    public void acceptReturner(ILibraryItemCollector collector) {
        throw new UnsupportedOperationException("Movies can't be returned yet.");
    }

    @Override
    public boolean isAvailable() {
        return isAvailable;
    }

    @Override
    public void setAvailable(boolean isAvailable) {
        this.isAvailable = isAvailable;
    }

    @Override
    public int compareTo(Movie otherMovie) {
        if (otherMovie == null) {
            return 1;
        }
        if (this.year == otherMovie.year) {
            int compareTitle = String.CASE_INSENSITIVE_ORDER.compare(this.title, otherMovie.title);
            if (compareTitle == 0) {
                return String.CASE_INSENSITIVE_ORDER.compare(this.director, otherMovie.director);
            }
            return compareTitle;
        }
        return this.year - otherMovie.year;
    }

    /**
     * Two movies are considered equal if they have the same Movie Id.
     *
     * @param o - Other object
     * @return <b>true</b> if same Movie Id; <b>false</b> otherwise
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Movie movie = (Movie) o;

        return !(movieId != null ? !movieId.equals(movie.movieId) : movie.movieId != null);
    }

    @Override
    public int hashCode() {
        return movieId != null ? movieId.hashCode() : 0;
    }

    @Override
    public String toString() {
        return formatString(movieId, Integer.toString(year), title, director, rating.toString());
    }

    public static String formatString(String movieId, String year, String title, String director, String rating) {
        return String.format("%-15s %-5s %-40s %-25s %s", movieId, year, title, director, rating);
    }
}
